﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using IrisGenerator.Common.Tools;
using System.Windows.Forms;
using IrisGenerator.Framework.Reflection;

//TODO: Les méthodes ne sont pas blindées... En particulier pour les entiers avec l'utilisation 
// de parse au lieu de try parse...

namespace IrisGenerator.Common.Core.UI
{
    public class ListTemplate
    {

        #region ListItemTemplate

        public class ListItemTemplate:ListSubItemTemplate
        {

            private List<ListSubItemTemplate> _subItemTemplates;
            private Dictionary<string, object> _keys;

            public int GroupId { get; set; }
            public string GroupIdData { get; set; }

            public string GroupName { get; set; }
            public string GroupNameData { get; set; }

            public int ImageIndex { get; set; }
            public string ImageIndexData { get; set; }

            public int StateImageIndex { get; set; }
            public string StateImageIndexData { get; set; }

            public string ToolTipText { get; set; }
            public string ToolTipTextData { get; set; }

            public bool UseItemStyleForSubItems { get; set; }
            public string UseItemStyleForSubItemsData { get; set; }


            public Dictionary<string, object> Keys
            {
                get
                {
                    if (_keys == null)
                        _keys = new Dictionary<string, object>();
                    return _keys;
                }
            }
            public List<ListSubItemTemplate> SubItemTemplates {
                get
                {
                    if (_subItemTemplates == null)
                        _subItemTemplates = new List<ListSubItemTemplate>();
                    return _subItemTemplates;
                }
            }
        }

        #endregion

        #region ListSubItemTemplate

        public class ListSubItemTemplate
        {
            
            public Color BackColor { get; set; }
            public string BackColorData { get; set; }

            public Font Font { get; set; }
            public string FontData { get; set; }

            public Color ForeColor { get; set; }
            public string ForeColorData { get; set; }

            public string Name { get; set; }
            public string NameData { get; set; }

            public string Text { get; set; }
            public string TextData { get; set; }
            
        }

        #endregion

        #region ListGroupTemplate

        public class ListGroupTemplate
        {
            public string Header { get; set; }
            public string Name { get; set; }
            public string MethodName { get; set; }
        }

        #endregion

        #region Properties

        public ListItemTemplate ItemTemplate { get; set; }
        public ListItemTemplate AlternateItemTemplate { get; set; }
        public ListGroupTemplate GroupsTemplate { get; set; }

        #endregion

        #region Methods

        #region LoadSubItem

        private static void LoadListItemSubItemTemplates(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null || template.SubItemTemplates == null)
                return;
            foreach (ListTemplate.ListSubItemTemplate subTemplate in template.SubItemTemplates)
            {
                ListViewItem.ListViewSubItem subItem = new ListViewItem.ListViewSubItem();

                LoadListSubItemBackColor(subItem, subTemplate, source);
                LoadListSubItemFont(subItem, subTemplate, source);
                LoadListSubItemForeColor(subItem, subTemplate, source);
                LoadListSubItemName(subItem, subTemplate, source);
                LoadListSubItemText(subItem, subTemplate, source);

                item.SubItems.Add(subItem);
            }

        }

        private static void LoadListSubItemText(ListViewItem.ListViewSubItem subItem, ListSubItemTemplate subTemplate, object source)
        {
            if (subItem == null || subTemplate == null)
                return;

            if (string.IsNullOrEmpty(subTemplate.TextData))
            {
                if (string.IsNullOrEmpty(subTemplate.Text))
                    return;
                subItem.Text = subTemplate.Text;
            }
            else
            {
                object value = Property.GetPropertyValue(source, subTemplate.TextData);
                if (value == null)
                    return;
                subItem.Text = value.ToString();
            }
        }

        private static void LoadListSubItemName(ListViewItem.ListViewSubItem subItem, ListSubItemTemplate subTemplate, object source)
        {
            if (subItem == null || subTemplate == null)
                return;

            if (string.IsNullOrEmpty(subTemplate.NameData))
            {
                if (string.IsNullOrEmpty(subTemplate.Name))
                    return;
                subItem.Name = subTemplate.Name;
            }
            else
            {
                string value = Property.GetPropertyValue(source, subTemplate.NameData) as string;
                if (value == null)
                    return;
                subItem.Name = value;
            }
        }

        private static void LoadListSubItemForeColor(ListViewItem.ListViewSubItem subItem, ListSubItemTemplate subTemplate, object source)
        {
            if (subItem == null || subTemplate == null)
                return;

            if (string.IsNullOrEmpty(subTemplate.ForeColorData))
            {
                if (subTemplate.ForeColor == null || subTemplate.ForeColor.IsEmpty)
                    return;
                subItem.ForeColor = subTemplate.ForeColor;
            }
            else
            {
                object value = Property.GetPropertyValue(source, subTemplate.ForeColorData);
                if (value is Color)
                    subItem.ForeColor = (Color)value;
            }
        }

        private static void LoadListSubItemFont(ListViewItem.ListViewSubItem subItem, ListSubItemTemplate subTemplate, object source)
        {
            if (subItem == null || subTemplate == null)
                return;

            if (string.IsNullOrEmpty(subTemplate.FontData))
            {
                if (subTemplate.Font == null)
                    return;
                subItem.Font = subTemplate.Font;
            }
            else
            {
                object value = Property.GetPropertyValue(source, subTemplate.FontData);
                if (value is Font)
                    subItem.Font = (Font)value;
            }
        }

        private static void LoadListSubItemBackColor(ListViewItem.ListViewSubItem subItem, ListSubItemTemplate subTemplate, object source)
        {
            if (subItem == null || subTemplate == null)
                return;

            if (string.IsNullOrEmpty(subTemplate.BackColorData))
            {
                if (subTemplate.BackColor == null || subTemplate.BackColor.IsEmpty)
                    return;

                subItem.BackColor = subTemplate.BackColor;
            }
            else
            {
                object value = Property.GetPropertyValue(source, subTemplate.BackColorData);
                if (value is Color)
                    subItem.BackColor = (Color)value;
            }
        }


        #endregion

        #region LoadItem

        private static void LoadListItemBackColor(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.BackColorData))
            {
                if (template.BackColor == null || template.BackColor.IsEmpty)
                    return;

                item.BackColor = template.BackColor;
            }
            else
            {
                object value = Property.GetPropertyValue(source, template.BackColorData);
                if (value is Color)
                    item.BackColor = (Color)value;
            }
        }

        private static void LoadListItemFont(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.FontData))
            {
                if (template.Font == null)
                    return;
                item.Font = template.Font;
            }
            else
            {
                object value = Property.GetPropertyValue(source, template.FontData);
                if (value is Font)
                    item.Font = (Font)value;
            }
        }

        private static void LoadListItemForeColor(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.ForeColorData))
            {
                if (template.ForeColor == null || template.ForeColor.IsEmpty)
                    return;
                item.ForeColor = template.ForeColor;
            }
            else
            {
                object value = Property.GetPropertyValue(source, template.ForeColorData);
                if (value is Color)
                    item.ForeColor = (Color)value;
            }
        }

        private static void LoadListItemName(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.NameData))
            {
                if (string.IsNullOrEmpty(template.Name))
                    return;
                item.Name = template.Name;
            }
            else
            {
                string value = Property.GetPropertyValue(source, template.NameData) as string;
                if (value != null)
                    item.Name = value;
            }
        }

        private static void LoadListItemGroupName(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null || item.ListView == null)
                return;

            string groupName = string.Empty;

            if (string.IsNullOrEmpty(template.GroupNameData))
            {
                if (string.IsNullOrEmpty(template.GroupName))
                    return;
                groupName = template.GroupName;
            }
            else
            {
                string value = Property.GetPropertyValue(source, template.GroupNameData) as string;
                if (value == null)
                    return;
                groupName = value;
            }

            foreach (ListViewGroup lvg in item.ListView.Groups)
            {
                if (lvg.Name.Equals(groupName))
                {
                    item.Group = lvg;
                    return;
                }
            }

        }

        private static void LoadListItemGroupId(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null || item.ListView == null)
                return;

            int groupId = -1;
            if (string.IsNullOrEmpty(template.GroupIdData))
            {
                if (template.GroupId < 0)
                    return;
                groupId = template.GroupId;
            }
            else
            {
                int result;
                if (int.TryParse(Property.GetPropertyValue(source, template.GroupIdData).ToString(), out result))
                    groupId = result;
            }

            if (groupId.Equals(-1))
                return;

            if (item.ListView.Groups.Count>groupId)
                item.Group = item.ListView.Groups[groupId];

        }

        private static void LoadListItemImageIndex(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.ImageIndexData))
            {
                item.ImageIndex = template.ImageIndex;
            }
            else
            {
                int result;
                if (int.TryParse(Property.GetPropertyValue(source, template.ImageIndexData).ToString(), out result))
                    item.ImageIndex = result;
            }
        }

        private static void LoadListItemStateImageIndex(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.StateImageIndexData))
            {
                item.StateImageIndex = template.StateImageIndex;
            }
            else
            {
                int result;
                if (int.TryParse(Property.GetPropertyValue(source, template.StateImageIndexData).ToString(), out result))
                    item.StateImageIndex = result;
            }
        }

        private static void LoadListItemText(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.TextData))
            {
                if (string.IsNullOrEmpty(template.Text))
                    return;
                item.Text = template.Text;
            }
            else
            {
                string value = Property.GetPropertyValue(source, template.TextData) as string;
                if (value == null)
                    return;
                item.Text = value.ToString();
            }
        }

        private static void LoadListItemToolTipText(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.ToolTipTextData))
            {
                if (string.IsNullOrEmpty(template.ToolTipText))
                    return;
                item.ToolTipText = template.ToolTipText;
            }
            else
            {
                string value = Property.GetPropertyValue(source, template.ToolTipTextData) as string;
                if (value == null)
                    return;
                item.ToolTipText = value;
            }
        }

        private static void LoadListItemUseStyleForSubItems(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.UseItemStyleForSubItemsData))
            {
                item.UseItemStyleForSubItems = template.UseItemStyleForSubItems;
            }
            else
            {
                bool result;
                if (bool.TryParse(Property.GetPropertyValue(source, template.UseItemStyleForSubItemsData).ToString(), out result))
                    item.UseItemStyleForSubItems = result;
            }
        }

        public static ListItem LoadItem(ListItem item, ListItemTemplate template, object source)
        {
            if (item == null || template == null)
                return item;

            LoadListItemBackColor(item, template, source);
            LoadListItemFont(item, template, source);
            LoadListItemForeColor(item, template, source);
            LoadListItemGroupId(item, template, source);
            LoadListItemGroupName(item, template, source);
            LoadListItemImageIndex(item, template, source);
            LoadListItemKeys(item, template, source);
            LoadListItemName(item, template, source);
            LoadListItemStateImageIndex(item, template, source);
            LoadListItemSubItemTemplates(item, template, source);
            LoadListItemText(item, template, source);
            LoadListItemToolTipText(item, template, source);
            LoadListItemUseStyleForSubItems(item, template, source);

            LoadListItemSubItemTemplates(item, template, source);

            LoadListItemKeys(item, template, source);

            return item;
        }

        #endregion

        #region Item Keys

        private static void LoadListItemKeys(ListItem item, ListItemTemplate template, object source)
        {

        }

        #endregion

        #region Groups

        public static void LoadListGroups(ListView list, ListGroupTemplate template, object source)
        {
            if (list == null || template == null || list.Groups==null)
                return;



            foreach (ListViewGroup lvg in list.Groups)
            {
                LoadListGroupName(lvg, template, source);
            }

        }

        private static void LoadListGroupName(ListViewGroup group, ListGroupTemplate template, object source)
        {
            if (group == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.Name))
                return;

            if (template.Name.StartsWith("#"))
                group.Name = Property.GetPropertyValue(source, template.Name.Substring(1)) as string;
            else
                group.Name = template.Name;
            
        }

        private static void LoadListGroupHeader(ListViewGroup group, ListGroupTemplate template, object source)
        {
            if (group == null || template == null)
                return;

            if (string.IsNullOrEmpty(template.Header))
                return;

            if (template.Name.StartsWith("#"))
                group.Header = Property.GetPropertyValue(source, template.Header.Substring(1)) as string;
            else
                group.Header = template.Header;

        }

        #endregion



        #endregion

    }
}
